﻿import-module ($Env:SMS_ADMIN_UI_PATH.Substring(0,$Env:SMS_ADMIN_UI_PATH.Length-5) + '\ConfigurationManager.psd1')

Add-Type -TypeDefinition @"
    //What type of maintenance to return
    public enum TypeOfMaintenanceWindow
    {
        Nonrecurring,
        RecurringEveryMonth,
        RecurringEveryWeekDay,
        RecurringCustomInterval
    }
"@


Function Create-MaintenanceWindow
{
param
(
    [Parameter(Mandatory=$true)]$MaintenanceWindow,
    [Parameter(Mandatory=$true)]$DeviceCollectionName,
    [Parameter(Mandatory=$true)]$Plus1Month,
    [Parameter(Mandatory=$true)]$PSDrive
)

    cd ($PSDrive+":")

    #Get the Device Collection we are removing and adding a new MW
    $Collection = Get-CMDeviceCollection -Name $DeviceCollectionName

    if ($Collection -ne $null)
    {
        $Schedule = Create-CMSchedule -CMScheduleParameter $MaintenanceWindow -Plus1Month $Plus1Month

        if(((Get-CMMaintenanceWindow -CollectionID $Collection.CollectionID) | where Name -eq $MaintenanceWindow.Name) -ne $null)
        {
            Remove-CMMaintenanceWindow -CollectionID $Collection.CollectionID -Name $MaintenanceWindow.Name -Force #remove old if exist
        }
        if($MaintenanceWindow.Enabled -eq $true)
        {
            New-CMMaintenanceWindow -CollectionID $Collection.CollectionID -Name $MaintenanceWindow.Name -Schedule $Schedule
        }
    }
}

Function Get-NewCMSchedule
{
param
(
    [Parameter(Mandatory=$true)]$MaintenanceWindow,
    [Parameter(Mandatory=$true)]$Plus1Month
)

        #Run at specific date
        if( ([System.Convert]::ToBoolean($MaintenanceWindow.Nonrecurring)) -eq $true)
        {
            $start = $MaintenanceWindow.startdate +" "+ $MaintenanceWindow.starttime
            $end = $MaintenanceWindow.startdate +" "+  $MaintenanceWindow.endtime
            $Schedule = New-CMSchedule -Nonrecurring -Start $start -End $end
        }
        else
        {#run recurring every month/week
            $MaintenanceWindowStartDate = Get-WeekDayInMonth -Month ([int](Get-Date).Month) -year ([int](Get-Date).Year) -Day ([DayToReturnInMonth]::($MaintenanceWindow.StartDate)) -Plus1Month $Plus1Month
            $StartTime = ([Datetime]$MaintenanceWindow.starttime)
            $MaintenanceWindowStartDate = $MaintenanceWindowStartDate.AddHours($StartTime.Hour)

            $Schedule = New-CMSchedule -DurationCount ([int]$MaintenanceWindow.DurationCount) -DurationInterval ([Microsoft.ConfigurationManagement.Cmdlets.Common.ScheduleInterval]::($MaintenanceWindow.DurationInterval))  -RecurCount $MaintenanceWindow.RecurCount -WeekOrder ([Microsoft.ConfigurationManagement.Cmdlets.Common.ScheduleWeekOrder]::($MaintenanceWindow.WeekOrder)) -DayOfWeek ([int]$MaintenanceWindow.DayOfWeek) -Start $MaintenanceWindowStartDate
        }

        $Schedule
}

Function Create-CMSchedule
{
param
(
    [Parameter(Mandatory=$true)]$CMScheduleParameter,
    [Parameter(Mandatory=$true)]$Plus1Month
)
    $CMScheduleParameters = @{}

    switch([TypeOfMaintenanceWindow]::($CMScheduleParameter.TypeOfMaintenanceWindow))
    {
        Nonrecurring
        {
            $start = $CMScheduleParameter.startdate +" "+ $CMScheduleParameter.starttime
            $end = $CMScheduleParameter.startdate +" "+  $CMScheduleParameter.endtime
            $CMScheduleParameters.Add("Start",$start)
            $CMScheduleParameters.Add("End",$end)

            $Schedule = New-CMSchedule -Nonrecurring -Start $start -End $end
        }

        RecurringEveryMonth
        {
            $MaintenanceWindowStartDate = Get-WeekDayInMonth -Month ([int](Get-Date).Month) -year ([int](Get-Date).Year) -Day ([DayToReturnInMonth]::($CMScheduleParameter.StartDate)) -Plus1Month $false
            $StartTime = ([Datetime]$CMScheduleParameter.starttime)
            $MaintenanceWindowStartDate = $MaintenanceWindowStartDate.AddHours($StartTime.Hour)

            $Schedule = New-CMSchedule -DurationCount ([int]$CMScheduleParameter.DurationCount) -DurationInterval ([Microsoft.ConfigurationManagement.Cmdlets.Common.ScheduleInterval]::($CMScheduleParameter.DurationInterval))  -RecurCount $CMScheduleParameter.RecurCount -WeekOrder ([Microsoft.ConfigurationManagement.Cmdlets.Common.ScheduleWeekOrder]::($CMScheduleParameter.WeekOrder)) -DayOfWeek ([int]$CMScheduleParameter.DayOfWeek) -Start $MaintenanceWindowStartDate
        }

        RecurringEveryWeekDay
        {#TODO RecurringEveryWeekDay

        }

        RecurringCustomInterval
        {
            $MaintenanceWindowStartDate = Get-WeekDayInMonth -Month ([int](Get-Date).Month) -year ([int](Get-Date).Year) -Day ([DayToReturnInMonth]::($CMScheduleParameter.StartDate)) -Plus1Month $false
            $StartTime = ([Datetime]$CMScheduleParameter.starttime)
            $MaintenanceWindowStartDate = $MaintenanceWindowStartDate.AddHours($StartTime.Hour)

            $Schedule = New-CMSchedule -RecurInterval ([Microsoft.ConfigurationManagement.Cmdlets.Common.ScheduleInterval]::($CMScheduleParameter.DurationInterval))  -RecurCount $CMScheduleParameter.RecurCount -Start $MaintenanceWindowStartDate
        }
    }
    
    $Schedule
}

Function Create-CMScheduleParameters
{
param
(
    [Parameter(Mandatory=$true)]$CMScheduleParameters
)

    foreach ($CMScheduleParameter in $CMScheduleParameters)
    {
        if( ([System.Convert]::ToBoolean($CMScheduleParameter.Enabled)) -eq $true)
        {#Create new CMSchedule
            Create-CMSchedule -CMScheduleParameter $CMScheduleParameter -Plus1Month $false
        }
    }

}

Function Create-MaintenanceWindows
{
param
(
    [Parameter(Mandatory=$true)][xml]$xmlDocumentWithConfiguration 
)

    $SoftwareUpdateDeployments = $xmlDocumentWithConfiguration.ADRs.SoftwareUpdateDeployments.SoftwareUpdateDeployment
    foreach($SoftwareUpdateDeployment in $SoftwareUpdateDeployments)
    {
        $MaintenanceWindows = $SoftwareUpdateDeployment.MaintenanceWindows.MaintenanceWindow
        foreach($MaintenanceWindow in $MaintenanceWindows)
        {
            Create-MaintenanceWindow -MaintenanceWindow $MaintenanceWindow -DeviceCollectionName $SoftwareUpdateDeployment.CollectionName -Plus1Month ([System.Convert]::ToBoolean($SoftwareUpdateDeployment.Plus1Month)) -PSDrive $xmlDocumentWithConfiguration.ADRs.Common.PSDrive
        }        
    }
}